package com.codinghero.zqlb.weibo.sina.bo;

import java.io.UnsupportedEncodingException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;

import com.codinghero.core.dao.NameValDao;
import com.codinghero.core.dto.NameVal;
import com.codinghero.util.DateUtils;
import com.codinghero.util.ListUtils;
import com.codinghero.util.StringUtils;
import com.codinghero.zqlb.match.DateSortableComparator;
import com.codinghero.zqlb.match.SoccerMatch;
import com.codinghero.zqlb.spider.bo.MatchBo;
import com.codinghero.zqlb.weibo.sina.dao.WeiboDao;
import com.codinghero.zqlb.weibo.sina.driver.SaeOAuthWeiboDriver;
import com.codinghero.zqlb.weibo.sina.dto.Weibo;

public class WeiboBo {
	
	private static Logger log = Logger.getLogger(WeiboBo.class);
	
	private MatchBo matchBo = new MatchBo();
	private WeiboDao weiboDao = new WeiboDao();
	private NameValDao nameValDao = new NameValDao();
	private SaeOAuthWeiboDriver weiboDriver = new SaeOAuthWeiboDriver();

	private static final int DAYS = 10;										// 天跨度
	private static final int[] POST_HOURS = new int[] { 7, 12, 21 };		// 微博发送时间

	public void calHotMatchWeibo() {
		List<ArrayList<SoccerMatch>> all = matchBo.getHotMatches(DAYS, POST_HOURS);
		List<Weibo> weibos = new ArrayList<Weibo>();
		if (all.size() > 0) {
			// 按时间段取出比赛列表，拼接微博
			for (ArrayList<SoccerMatch> periodHotMatches : all) {
				String weiboDes = this.getWeiboDes(periodHotMatches);
				if (!StringUtils.isEmpty(weiboDes)) {
					Weibo weibo = new Weibo();
					weibo.setDes(weiboDes);
					// 确定微博发送日期&发送序号
					int hour = Integer.parseInt(DateUtils.getDateStr(periodHotMatches.get(0).getStartDate(), "H"));
					weibo.setCurDate(periodHotMatches.get(0).getStartDate());
					if (hour < POST_HOURS[0])
						weibo.setCurDate(weibo.getCurDate() - 1);
					weibo.setSeq(this.getSeq(hour));
					weibos.add(weibo);
				}
			}
		}
		removeExistWeibo(weibos);
		insertWeibos(weibos);
	}
	
	private int getSeq(int hour) {
		for (int i = 0; i < POST_HOURS.length; i++) {
			if (hour < POST_HOURS[i])
				return (i - 1 + POST_HOURS.length) % POST_HOURS.length;
		}
		return POST_HOURS.length - 1;
	}
		
	private String getWeiboDes(List<SoccerMatch> matches) {

		if (matches == null || matches.size() == 0)
			return null;
		
		// 1. 取得比赛信息列表且长度不超过95（额外40字显示别的信息）
		StringBuilder sb = new StringBuilder();
		List<SoccerMatch> weiboMatches = new ArrayList<SoccerMatch>();
		for (SoccerMatch match : matches) {
			int len;
			try {
				len = (sb.toString() + match.getShortInfo()).getBytes("GBK").length / 2 + 1;
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
				continue;
			}
			if (len > 110)	// 可以接受113，设定为110比较保险
				break;
			else {
				weiboMatches.add(match);
				sb.append("，");
				sb.append(match.getShortInfo());
			}
		}
		sb = new StringBuilder();	//清空上边的临时处理数据
		
		// 2. 将比赛分为两组（因为时间有可能跨天）
		Collections.sort(weiboMatches, new DateSortableComparator());

		List<SoccerMatch> curDayMatches = new ArrayList<SoccerMatch>();
		List<SoccerMatch> nextDayMatches = new ArrayList<SoccerMatch>();
		
		Calendar firstDate = Calendar.getInstance();
		firstDate.setTime(weiboMatches.get(0).getStartDate());
		Calendar secondDate = null;
		
		for (int i = 0; i < weiboMatches.size(); i++) {
			SoccerMatch match = weiboMatches.get(i);
			if (secondDate == null) {
				Calendar matchDate = Calendar.getInstance();
				matchDate.setTime(match.getStartDate());
				if (firstDate.get(Calendar.DAY_OF_MONTH) != matchDate.get(Calendar.DAY_OF_MONTH)) {
					secondDate = matchDate;
				}
			}
			
			if (secondDate == null) {
				curDayMatches.add(match);
			} else {
				nextDayMatches.add(match);
			}
		}
		
		// 3. 拼接两组微博的内容
		// 当天预告
		if (ListUtils.isEmpty(curDayMatches)) {
			return null;
		} else {
			sb.append(DateUtils.getDateStr(curDayMatches.get(0).getStartDate(), "M月d日E，"));
			sb.append(SoccerMatch.getShortInfo(curDayMatches));
		}
		// 第二天预告
		if (!ListUtils.isEmpty(nextDayMatches)) {
			sb.append("；");
			sb.append(DateUtils.getDateStr(nextDayMatches.get(0).getStartDate(), "M月d日E，"));
			sb.append(SoccerMatch.getShortInfo(nextDayMatches));
		}
		// 直播链接
		sb.append("。❤直播链接-> http://t.cn/zOBchPU");
		try {
			if (sb.toString().getBytes("GBK").length / 2 > 140)
				System.err.println(DateUtils.getDateStr(curDayMatches.get(0).getStartDate(), "M月d日，") + "微博长度超过140");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return null;
		}
		return sb.toString();
	}
	
	private void removeExistWeibo(List<Weibo> weibos) {
		List<Weibo> existWeibos = getHotMatchWeibo();
		Iterator<Weibo> iter = weibos.iterator();
		while(iter.hasNext()) {
			Weibo weibo = iter.next();
			for (int i = 0; i < existWeibos.size(); i++) {
				if (weibo.getCurDate().equals(existWeibos.get(i).getCurDate())
						&& weibo.getSeq() == existWeibos.get(i).getSeq()) {
					iter.remove();
					break;
				}
			}
		}
	}
	
	public List<Weibo> getHotMatchWeibo() {
		
		int startDateInt = Integer.parseInt(DateUtils.getDateStr(new Date(), "yyyyMMdd"));
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DAY_OF_MONTH, DAYS);
		int endDateInt = Integer.parseInt(DateUtils.getDateStr(calendar.getTime(), "yyyyMMdd"));
		
		try {
			weiboDao.connect();
			return weiboDao.getAllWeiboByDateRange(startDateInt, endDateInt);
		} catch (SQLException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		} finally {
			weiboDao.close();
		}
	}
	
	public void postHotMatchWeibo(int seq) {
		try {
			weiboDao.connect();
			nameValDao.connect();
			int curDateInt = Integer.parseInt(DateUtils.getDateStr(new Date(), "yyyyMMdd"));
			Weibo weibo = weiboDao.getValidWeiboByDateAndSeq(curDateInt, seq);
			NameVal nameVal = nameValDao.getNameValByName("ACCESS_TOKEN");
			log.debug("when postHotMatchWeibo the accessToken is " + nameVal.getVal());
			if (weibo != null && !StringUtils.isEmpty(weibo.getDes())){
				log.debug(weibo.getDes());
				weiboDriver.post(nameVal.getVal(), weibo.getDes());
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			nameValDao.close();
			weiboDao.close();
		}
	}
	
	public void insertWeibos(List<Weibo> weibos) {
		try {
			weiboDao.connect();
			weiboDao.startTransaction();
			for (Weibo weibo : weibos) {
				weiboDao.deleteWeiboByDateAndSeq(weibo.getCurDate(), weibo.getSeq());
				weiboDao.insertWeibo(weibo);
			}
			weiboDao.commit();
		} catch (SQLException e) {
			weiboDao.rollback();
			e.printStackTrace();
		} finally {
			weiboDao.close();
		}
	}
}
